package gonat

import (
	"fmt"
	"net"
	"strings"
	"time"

	natpmp "github.com/jackpal/go-nat-pmp"
)

// UpnpNatDevice upnp接口实现
type PmpNatDevice struct {
	LocalAddress string

	err error

	gw net.IP

	c *natpmp.Client
}

// AddPortMapping Creates the port map .
// <example>
// </example>
func (device *PmpNatDevice) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) {
	if NewLeaseDuration <= 0 {
		return fmt.Errorf("lifetime must not be <= 0")
	}
	// Note order of port arguments is switched between our
	// AddMapping and the client's AddPortMapping.
	_, _err := device.c.AddPortMapping(strings.ToLower(NewProtocol), int(NewInternalPort), int(NewExternalPort), int(time.Duration(NewLeaseDuration)/time.Second))

	return _err
}

//
// Return values:
//
// * NewProtocol: allowed values: TCP, UDP
func (device *PmpNatDevice) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) {

	return
}

//
// Arguments:
//
// * NewProtocol: allowed values: TCP, UDP

func (device *PmpNatDevice) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) {

	return
}

//
// Arguments:
//
// * NewProtocol: allowed values: TCP, UDP

func (device *PmpNatDevice) DeletePortMapping(NewRemoteHost string, ExternalPort uint16, InternalPort uint16, Protocol string) (err error) {
	// To destroy a mapping, send an add-port with an internalPort of
	// the internal port to destroy, an external port of zero and a
	// time of zero.
	_, err = device.c.AddPortMapping(strings.ToLower(Protocol), int(InternalPort), 0, 0)
	return err
}

func (device *PmpNatDevice) GetExternalIPAddress() (NewExternalIPAddress string, err error) {
	response, err := device.c.GetExternalAddress()
	if err != nil {
		return "", err
	}
	return net.IP(response.ExternalIPAddress[:]).String(), nil
}
